sale:
	proc;
	/* sale mode */
	%replace
		true  by '1'b,
		false by '0'b;

	%include 'attrib.dcl';

	%include 'key.dcl';

	dcl
		prc_start fixed ext,
		prc_len   fixed ext,
		qty_start fixed ext,
		qty_len   fixed ext,
		sales_tax dec(4,2) ext;
	dcl
		list  file,
		sysin  file,
		device char(11) var,
		rec    char(max_siz);
	dcl
		open_data   entry,
		close_data  entry,
		input_key   entry(char(max_siz)),
		locate_key  entry(char(max_siz)) returns(bit),
		alter_rec   entry(char(max_siz)),
		att_len     entry(fixed) returns(fixed);

	on endfile(sysin)
		go to end_sale;

	call open_data();
	put edit('Sales Mode','')(skip,a);
		do while(true);
		/* read next request */
		put skip list('Output To: ');
		get list(device);
		open file(list) print title(device);
		put file(list) page;
		call transaction();
		close file(list);
		end;

	dcl
		qty         fixed,
		qty_sold    fixed,
		item_no     fixed,
		total_price dec(10,2);

	transaction:
		proc;
		on endfile(sysin)
			go to summary;
		on error(1)
			begin;
			put edit('Bad Data in Record','')
				(column(4),a,skip,a);
			go to retry;
			end;
		call header();
		total_price = 0.00;
		item_no     = 1;
		retry:
			do while(true);
			call input_key(rec);
			if locate_key(rec) then
				do;
				put edit('Quantity Sold')
					(column(4),a(max_chr));
				get list(qty_sold);
				qty = get_qty();
				if qty_sold > qty then
					call too_few();
				else
					call itemize();
				end;
			end;
		summary:
		call trailer();
		end transaction;

	itemize:
		proc;
		/* process one item */
		dcl
			line_price dec(10,2),
			item_price dec(10,2);
		item_price = get_price();
		line_price = dec(qty_sold,3) * item_price;
		put file(list) edit('|',item_no,
			'|',substr(rec,att_start(1),att_len(1)),
			'|',qty_sold,
			'|',item_price,
			'|',line_price,'|')
			(skip, a,f(2), a,a(max_chr), a,f(3),
			a,p'$,$$9V.99', a,p'$$,$$9V.99', a);
		/* operation sucessful, change record */
		total_price = total_price + line_price;
		item_no = item_no + 1;
		call set_qty (qty - qty_sold);
		call alter_rec(rec);
		end itemize;

	header:
		proc;
		/* write the invoice header */
		call line();
		put file(list) edit
		('| #|','Item','|Qty|  Price | Sub Tot |')
			(skip,a,a(max_chr),a);
		call line();
		end header;

	trailer:
		proc;
		/* write summary records */
		dcl
			tax dec(10,2);
		call line();
		put file(list) edit
			('|','Sub Total','',total_price,'|') (r(fmt));
		tax = total_price * sales_tax / 100 + .005;
		put file(list) edit
			('|','Sales Tax','',tax,'|') (r(fmt));
		total_price = total_price + tax;
		call line();
		put file(list) edit
			('|','Total','',total_price,'|') (r(fmt));
		call line();
		fmt: format
			(skip, a,a(15),a(max_chr),p'$ZZZ,ZZ9V.99',a);
		end trailer;

	line:
		proc;
		/* write a line of '-' */
		dcl
			i fixed;
		put file(list) skip edit
			(('-' do i = 1 to max_chr + 28)) (a);
		end line;

	get_price:
		proc returns(dec(10,2));
		/* get price field for current record */
		dcl
			i fixed,
			v char(max_chr) var;
		v = substr(rec,prc_start,prc_len);
		/* remove trailing blanks */
		i = verify(v,'0123456789.');
		if i > 0 then
			v = substr(v,1,i-1);
		return (v);
		end get_price;

	get_qty:
		proc returns(fixed);
		/* get quantity for current record */
		return (substr(rec,qty_start,qty_len));
		end get_qty;

	set_qty:
		proc(c);
		/* set the quantity field for current record */
		dcl
			c fixed,
			v char(9) var;
		v = c;
		substr(rec,qty_start,qty_len) =
			substr(v,verify(v,' '));
		end set_qty;

	too_few:
		proc;
		put edit('Only',qty,'In Inventory','')
			(column(4),a,f(6),x(1),a,skip);
		end too_few;

	end_sale:
	call close_data();
	close file(list);
	end sale;
